package model.siec.definicja;

import model.liczba.ILiczba;
import model.liczba.IObslugaLiczba;

public class CSiecNeuronowaPrototyp implements ISiecNeuronowa {
	
	
	private int[] 				neuronyWarstwaLiczba ;
	private ILiczba[][][] 		wagaWartosci;
	private ILiczba[][] 		neuronWejscieWartosci;
	private ILiczba[][] 		neuronWartosci;
	private ILiczba[][] 		neuronBladWartosci;
	private ILiczba				uczenieWspolczynnik;
	private IObslugaLiczba		liczbaReprezentacja;
	private int					warstwyLiczba;
	

	private IFunkcjaAktywacja funkcjaAktywacja;
	private IFunkcjaWynikInterpretacja funkcjaWynikInterpretacja;
	
	public CSiecNeuronowaPrototyp() {}

	public CSiecNeuronowaPrototyp(
			int warstwyLiczba, 
			int maxNeuronyWarstwyLiczba,
			int [] neuronyWarstwyLiczba,
			IFunkcjaAktywacja funkcjaAktywacja,
			IFunkcjaWynikInterpretacja funkcjaWynikInterpretacja, 
			double uczenieWspolczynnik,
			IObslugaLiczba	liczbaReprezentacja) 
	{
		this.warstwyLiczba			= warstwyLiczba;
		this.neuronyWarstwaLiczba 	= neuronyWarstwyLiczba;
		this.wagaWartosci 			= new ILiczba[warstwyLiczba][maxNeuronyWarstwyLiczba][maxNeuronyWarstwyLiczba];
		this.neuronWejscieWartosci 	= new ILiczba[warstwyLiczba][maxNeuronyWarstwyLiczba];
		this.neuronWartosci			= new ILiczba[warstwyLiczba][maxNeuronyWarstwyLiczba];
		this.neuronBladWartosci		= new ILiczba[warstwyLiczba][maxNeuronyWarstwyLiczba];
		this.uczenieWspolczynnik 	= liczbaReprezentacja.create(uczenieWspolczynnik);
		this.funkcjaAktywacja 		= funkcjaAktywacja;
		this.funkcjaWynikInterpretacja 	= funkcjaWynikInterpretacja;		
		this.liczbaReprezentacja		= liczbaReprezentacja;
	}

	@Override
	public int getWarstwaNeuronyLiczba(int warstwa) {
		return neuronyWarstwaLiczba[warstwa];
	}

	@Override
	public int getWarstwyLiczba() {
		return warstwyLiczba;
	}

	@Override
	public ILiczba getWagaWartosc(
			int warstwaNumer, 
			int neuronWarstwyNumer,
			int neuronWarstwyWyzszejNumer) {
		return wagaWartosci[warstwaNumer][neuronWarstwyNumer][neuronWarstwyWyzszejNumer];
	}

	@Override
	public ILiczba getNeuronWartosc(int warstwaNumer, int neuronWarstwyNumer) {
		return neuronWartosci[warstwaNumer][neuronWarstwyNumer];
	}
	
	@Override
	public void setNeuronWartosc(
			int warstwaNumer, 
			int neuronWarstwyNumer,
			ILiczba neuronWartosc) {
		neuronWartosci[warstwaNumer][neuronWarstwyNumer] = neuronWartosc;
	}

	@Override
	public void setWagaWartosc(
			int warstwaNumer, 
			int neuronWarstwyNumer,
			int neuronWarstwyWyzszejNumer, 
			ILiczba wagaWartosc) {
		wagaWartosci[warstwaNumer][neuronWarstwyNumer][neuronWarstwyWyzszejNumer] = wagaWartosc;
	}

	@Override
	public ILiczba getNeuronWejscieWartosc(
			int warstwaNumer,
			int neuronWarstwyNumer) {
		return neuronWejscieWartosci[warstwaNumer][neuronWarstwyNumer];
	}

	@Override
	public void setNeuronWejscieWartosc(
			int warstwaNumer,
			int neuronWarstwyNumer, 
			ILiczba neuronWartosc) {
		neuronWejscieWartosci[warstwaNumer][neuronWarstwyNumer] = neuronWartosc;
	}

//	public CLiczba getFunkcjaWartosc(CLiczba argument) {
//		return funkcjaAktywacja.getFunkcjaWartosc(argument);
//	}
//
//	public CLiczba getFunkcjaPochodnaWartosc(CLiczba argument) {
//		return funkcjaAktywacja.getFunkcjaPochodnaWartosc(argument);
//	}

	@Override
	public ILiczba getUczenieWspolczynnik() {
		return uczenieWspolczynnik;
	}

	@Override
	public ILiczba getNeuronBladWartosc(int warstwaNumer, int neuronWarstwyNumer) {
		return neuronBladWartosci[warstwaNumer][neuronWarstwyNumer];
	}

	@Override
	public void setNeuronBlad(
			int warstwaNumer, 
			int neuronWarstwyNumer,
			ILiczba neuronBlad) {
		neuronBladWartosci[warstwaNumer][neuronWarstwyNumer] = neuronBlad;
	}

	@Override
	public IFunkcjaWynikInterpretacja getFunkcjaWynikInterpretacja() {
		return funkcjaWynikInterpretacja;
	}

	@Override
	public IFunkcjaAktywacja getFunkcjaAktywacja() {
		return funkcjaAktywacja;
	}

	public void setFunkcjaAktywacja(IFunkcjaAktywacja funkcjaAktywacja) {
		this.funkcjaAktywacja = funkcjaAktywacja;
	}
	
	public String toString() {
		String wynik = "";
		int warstwyLiczba = getWarstwyLiczba()-1;
		for (int i=0; i<getWarstwaNeuronyLiczba(warstwyLiczba); i++) {
			wynik += i+": "+getNeuronWartosc(warstwyLiczba, i)+" ";
		}

		return wynik;
	}

	@Override
	public IObslugaLiczba getObslugaLiczba() {
		return liczbaReprezentacja;
	}
}
